﻿using System;
using System.Linq;
using SSG.Tools;

namespace SSG.Model
{
    /// <summary>
    /// Fixpoint on same position like navaid, but not the navaid.
    /// ABNB -> ABSAM, Fixpoint on ABSAM position, but different name. 
    /// </summary>
    /// <seealso cref="FindEquivalentNavaidDetails"/>
    public class FixOnNavaidPosition : Navaid
    {
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="name"></param>
        /// <param name="type"></param>
        /// <param name="canoncialName"></param>
        /// <param name="description"></param>
        /// <param name="lat"></param>
        /// <param name="lng"></param>
        public FixOnNavaidPosition(string name, NavaidType type, string canoncialName = null, string description = null, double lat = 0, double lng = 0)
            : base(name, type, canoncialName, description, lat, lng)
        {
            // code goes here
        }

        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="navaid"></param>
        public FixOnNavaidPosition(Navaid navaid) : base(navaid.Name, navaid.Type, navaid.CanonicalName, navaid.Description, navaid.Latitude, navaid.Longitude)
        {
            if (navaid == null) throw new ArgumentNullException("navaid");
            this.Frequency = navaid.Frequency;
            this.DataRawString = navaid.DataRawString;
            this.IsCalculated = navaid.IsCalculated;
        }

        /// <summary>
        /// Get the "real" navaid
        /// </summary>
        /// <param name="fixpoint"></param>
        /// <returns></returns>
        public static Fix FindEquivalentNavaidDetails(Fix fixpoint)
        {
            if (fixpoint == null) return null;
            if (String.IsNullOrEmpty(fixpoint.Name)) return fixpoint;
            Navaid navaid = fixpoint as Navaid;
            if (navaid != null) return new FixOnNavaidPosition(navaid); // already navaid
            if (Navaids.NullSafeIsEmpty()) return null;

            // try to find the exact Navaid
            navaid = Navaids.FirstOrDefault(na => na.Name.Equals(fixpoint.Name) && na.SamePosition(fixpoint));
            if (navaid != null) return new FixOnNavaidPosition(navaid); // found

            // fixpoint on same position?
            if (fixpoint.Name.EndsWith("NB")) {
                String ndb = fixpoint.Name.Substring(0, fixpoint.Name.Length - 2);
                navaid = Navaids.FirstOrDefault(na => na.Name.Equals(ndb) && na.SamePosition(fixpoint));
                if (navaid != null) {
                    // Fixpoint looks like navaid, but "is" not exactly the navaid
                    return new FixOnNavaidPosition(navaid) {Name = fixpoint.Name};
                }
            }
            return fixpoint;
        }

        /// <summary>
        /// Clone object
        /// </summary>
        /// <returns></returns>
        public override object Clone()
        {
            return new FixOnNavaidPosition(this);
        }

    }
}